package mobi.greenplate.theweb.resource;

import java.net.URI;
import java.util.List;
import javax.inject.Inject;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import mobi.greenplate.theweb.converter.TransportConverter;
import mobi.greenplate.theweb.converter.TransportListConverter;
import mobi.greenplate.theweb.domain.Transport;
import mobi.greenplate.theweb.domain.User;
import mobi.greenplate.theweb.repository.TransportRepository;
import mobi.greenplate.theweb.repository.UserRepository;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

@Path("/user/{userId}/transport")
@Component
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class TransportResource {

    @Inject
    private TransportRepository transportRepository;
    @Inject
    private UserRepository userRepository;
    @Context
    private UriInfo uriInfo;

    @GET
    @Produces({"application/xml", "application/json"})
    public TransportListConverter getTransports(
            @QueryParam("first") @DefaultValue("0") int first,
            @QueryParam("max") @DefaultValue("10") int max,
            @PathParam("userId") Long ownerId) {
        final List<Transport> transportList = transportRepository.findByOwner(first, max, ownerId);
        final TransportListConverter transportListConverter = new TransportListConverter(transportList);
        return transportListConverter;
    }

    @GET
    @Produces({"application/xml", "application/json"})
    @Path("{id}")
    public TransportConverter getTransportById(@PathParam("id") Long id, @PathParam("userId") Long ownerId) {
        try {
            final Transport transport = transportRepository.findById(id);
            if (!transport.getOwner().getId().equals(ownerId)) {
                throw new NotFoundException(" not found transport with id=" + id + " of user with id=" + ownerId);
            }
            final TransportConverter transportConverter = new TransportConverter(transport);
            return transportConverter;
        } catch (IllegalArgumentException ex) {
            throw new NotFoundException(ex.getMessage());
        }
    }

    @POST
    @Consumes({"application/xml", "application/json"})
    public Response createTransport(@PathParam("userId") Long ownerId, TransportConverter transportConverter) {
        final Transport forSave = transportConverter.getEntity();
        forSave.setId(null); //makes sure it is allways new..
        final User owner = userRepository.findById(ownerId);
        final Transport transport = transportRepository.save(forSave, owner);
        final URI uri = uriInfo.getAbsolutePathBuilder().
                path(transport.getId().toString()).
                build();
        return Response.created(uri).build();
    }

    @PUT
    @Consumes({"application/xml", "application/json"})
    @Path("{id}")
    public TransportConverter updateOrCreateTransport(@PathParam("id") Long id, @PathParam("userId") Long ownerId, TransportConverter transportConverter) {
        //if the resource doesn't exist.. it would be created...with PUT.. could be added additional check ...
        final Transport forSave = transportConverter.getEntity();
        forSave.setId(id); //makes sure it is exactly the one that has to be updated
        final User owner = userRepository.findById(ownerId);
        final Transport transport = transportRepository.save(forSave, owner);
        return new TransportConverter(transport);
    }

    @DELETE
    @Path("{id}")
    public void deleteTransport(@PathParam("id") Long id, @PathParam("userId") Long ownerId) {
        final Transport transport = transportRepository.findById(id);
        if (!transport.getOwner().getId().equals(ownerId)) {
            throw new NotFoundException(" not found transport with id=" + id + " of user with id=" + ownerId);
        }
        transportRepository.delete(id);
    }
}
